//****************************************************
// Porman Project 
// Filename: CRenderSystem.h
// Date: 2010/12/13
// Author: KengYu Lin
// Modify:
//****************************************************
#ifndef _CRENDERSYSTEM_H
#define _CRENDERSYSTEM_H
#include <map>
#include "porman_gl/include/CDeviceCreator.h"
#include "porman_gl/include/CRenderDevice.h"
#include "CRSDef.h"
#include "CRenderBase.h"
#include "CRenderCamera.h"
#include "CRenderTarget.h"
#include "CRenderUnity.h"
#include "CRenderWindow.h"

namespace Porman
{

namespace RS
{

class CRenderSystem : public CSingletonT<CRenderSystem>
{
public:
    PRS_API static CRenderSystem& getSingleton(void);
    PRS_API static CRenderSystem* getSingletonPtr(void);

    PRS_API CRenderSystem( CRenderSystemDesc& desc, IRenderMutex* pMutex = NULL );
    PRS_API virtual ~CRenderSystem( void );

    PRS_API bool initialise( CRenderWindow* pWindow );
    PRS_API bool isInitialised( void );
    PRS_API CRenderSystemDesc getRenderSystemDesc( void ) { return m_RenderSysDesc; }
    PRS_API const IRenderMutex& getMutex( void ) { return (*m_pMutex); }
    PRS_API const IRenderMutex* getMutexRef( void ) { return m_pMutex; }

    PRS_API CRenderWindow* createRenderWindow( HWND hWnd, const std::string& sName );
    PRS_API bool deleteRenderWindow( CRenderWindow** ppWindow );
    PRS_API CRenderWindow* getRenderWindow( const std::string& sName );
    PRS_API int getNumRenderWindows( void );

    PRS_API CRenderCamera* createRenderCamera( const std::string& sName );
    PRS_API bool deleteRenderCamera( CRenderCamera** ppCamera );
    PRS_API CRenderCamera* getRenderCamera( const std::string& sName );
    PRS_API int getNumRenderCamera( void );

    PRS_API CRenderUnity* createRednerUnity( const std::string& sName );
    PRS_API bool deleteRednerUnity( CRenderUnity** ppUnity );
    PRS_API CRenderUnity* getRednerUnity( const std::string& sName );
    PRS_API int getNumRenderUnity( void );

    PRS_API void onSwap( void ); //Sync region will call this member function to switch data.
    PRS_API void onRender( void ); //Rendering thread will call this member function to perform rendering.

    PRS_API GL::CRenderDevice* getDevice( void ) { return m_pDevice; }

protected:
    CRenderSystemDesc m_RenderSysDesc;
    GL::CRenderDevice* m_pDevice;

    bool m_bUsingDefaultRenderMutex;
    IRenderMutex* m_pMutex;

    CRenderBaseManagerT<CRenderUnity> m_mapRenderUnities;
    CRenderBaseManagerT<CRenderCamera> m_mapRenderCameras;
    CRenderBaseManagerT<CRenderWindow> m_mapRenderWindows;
};

}//End namespace RS

}//End namespace Porman

#endif